package net.orange.console.model.dataset;

import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.sql.rowset.CachedRowSet;

/**
 * The data set, it include one or more than row data.
 */
public class ConsoleDataSet {

	/**
	 * The row data set.
	 */
	private Collection<ConsoleRow> rows = new ArrayList<ConsoleRow>();
	/**
	 * The meta data of the dataset.
	 */
	private Map<String, ConsoleMetaData> metaDataSet = new HashMap<String, ConsoleMetaData>();

	/**
	 * @return the rows
	 */
	public Collection<ConsoleRow> getRows() {
		return rows;
	}

	/**
	 * @param rows
	 *            the rows to set
	 */
	public void setRows(Collection<ConsoleRow> rows) {
		this.rows = rows;
	}

	/**
	 * @return the size
	 */
	public int getSize() {
		return (rows != null) ? rows.size() : 0;
	}

	/**
	 * Append one row.
	 * 
	 * @param row
	 *            The target row.
	 */
	public void addRow(ConsoleRow row) {
		rows.add(row);
	}

	/**
	 * Remove one row
	 * 
	 * @param row
	 *            The target row.
	 */
	public void removeRow(ConsoleRow row) {
		rows.remove(row);
	}

	/**
	 * @return the metaDataSet
	 */
	public Map<String, ConsoleMetaData> getMetaDataSet() {
		return metaDataSet;
	}

	/**
	 * @param metaDataSet
	 *            the metaDataSet to set
	 */
	public void setMetaDataSet(Map<String, ConsoleMetaData> metaDataSet) {
		this.metaDataSet = metaDataSet;
	}

	/**
	 * Get the console meta data set iterator.
	 * 
	 * @return the console meta data set iterator.
	 */
	public Iterator getMetaDataSetIterator() {
		if (metaDataSet == null)
			return null;

		List list = new ArrayList();

		list.addAll(metaDataSet.values());

		Collections.sort(list, new ConsoleMetaDataComparator());

		return list.iterator();
	}

	/**
	 * Construct with console meta data set.
	 * 
	 * @param metaDataSet
	 *            The console meta data set.
	 */
	public ConsoleDataSet(Map<String, ConsoleMetaData> metaDataSet){
		for(String key : metaDataSet.keySet() ){
			this.metaDataSet.put(key, metaDataSet.get(key));
		}
	}

	/**
	 * Constructor with the Jdbc RowSet, It'will convert the Jdbc RowSet to
	 * Console DataSet.
	 * 
	 * @param rowSet
	 *            The target Jdbc RowSet.
	 * @throws Exception
	 */
	public ConsoleDataSet(CachedRowSet rowSet) throws Exception {
		long primaryKey = 0;

		if (rowSet != null) {
			ResultSetMetaData resultSetMetaData = rowSet.getMetaData();

			// format the console meta data.
			for (int i = 1; i <= resultSetMetaData.getColumnCount(); ++i) {
				ConsoleDataType dataType = ConsoleDataType
						.toDataType(resultSetMetaData.getColumnType(i));
				String columnName = resultSetMetaData.getColumnName(i);

				metaDataSet.put(columnName, new ConsoleMetaData(dataType,
						columnName, i));
			}
			// format the row data.
			while (rowSet.next()) {
				ConsoleRow row = new ConsoleRow(primaryKey, rowSet, metaDataSet);

				addRow(row);

				primaryKey++;
			}

		}
	}

}
